var async = require("async"); //version 1.5.2

//将一个Array中的元素，按照一定的规则转换，得到一个新的数组（元素个数不变)
async.map([6, 3, 9, 16, 2, 15], function (item, callback) {
  var _setValue = parseInt(item) + 1;
  callback(null, _setValue);
}, function (err, results) {

  console.log("map:" + results); // map:7,4,10,17,3,16
});

//和map一样，但是同步执行
async.mapSeries([6, 3, 9, 16, 2, 15], function (item, callback) {

  callback(null, parseInt(item) - 1);
}, function (err, results) {

  console.log("mapSeries:" + results); // mapSeries:5,2,8,15,1,14
});


//map限制并发个数
async.mapLimit([6, 3, 9, 16, 2, 15], 2, function (item, callback) {

  callback(null, parseInt(item) * 10);
}, function (err, results) {
  console.log("mapLimit:" + results); // mapLimit:60,30,90,160,20,150
});


//Array的迭代器方法
var newArray = [];
async.each([6, 3, 9, 16, 2, 15], function (item, callack) {
  var _setValue = parseInt(item) * 2;
  newArray.push(_setValue);
  callack(null);
}, function (err) {
  console.log("each:" + newArray); // each:12,6,18,32,4,30
});


//和each基本一样，但是顺序执行，API接口和参数都一样
newArray = [];
async.eachSeries([6, 3, 9, 16, 2, 15], function (item, callback) {

  newArray.push(parseInt(item) + 3);

  callback(null);
}, function (err) {
  console.log("eachSeries:" + newArray); // eachSeries:60,30,90,160,20,150,6,12,19,5,18
});


//也和each差不多，多出来的limit参数，是限制允许并发执行的任务数
newArray = [];
async.eachLimit([6, 3, 9, 16, 2, 15], 2, function (item, callback) {

  newArray.push(parseInt(item) * 10);
  callback(null);   // 必须调用，才能触发下一个任务执行

}, function (err) {

  console.log("eachLimit:" + newArray); // eachLimit:60,30,90,160,20,150
});


//过滤器
async.filter([6, 3, 9, 16, 2, 15], function (item, callback) {

  callback(parseInt(item) > 3);
}, function (results) {
  console.log("filter:" + results); // filter:6,9,16,15
});

//同步的过滤器
async.filterSeries([6, 3, 9, 16, 2, 15], function (item, callback) {

  callback(parseInt(item) > 2);
}, function (results) {
  console.log("filterSeries:" + results); // filterSeries:6,3,9,16,15
});


//和filter相同，但是取补
async.reject([6, 3, 9, 16, 2, 15], function (item, callback) {

  callback(parseInt(item) > 4);
}, function (results) {
  console.log("reject:" + results); // reject:3,2
});

//reject的同步方法
async.rejectSeries([6, 3, 9, 16, 2, 15], function (item, callback) {

  callback(parseInt(item) > 3);
}, function (results) {
  console.log("rejectSeries:" + results); // rejectSeries:3,2
});


//将一个数组中的元素，归并成一个元素
async.reduce([6, 3, 9, 16, 2, 15], 0, function (memo, item, callback) {

  callback(null, memo + item)

}, function (err, result) {

  if (err) {
    console.error("reduce error: " + err);
    return;
  }

  console.log("reduce:" + result); // reduce:51
});


//对数组中的元素进行迭代操作，形成一个新数组
async.concat([6, 3, 9, 16, 2, 15], function (item, callback) {

  callback(null, [item + 1, item + 2]);

}, function (err, results) {

  console.log("concat:" + results); //7,8,4,5,10,11,17,18,3,4,16,17

});


/**
 * 同名函数all。跟some相反，如果数组中所有元素都满足条件，则返回true，否则返回false
 */
async.every([6, 3, 9, 16, 2, 15], function (item, callback) {
  callback(item < 10);

}, function (result) {

  console.log("every:" + result);// false  16不满足条件，后面的2,5不再遍历

});

// 从数组中找出符合条件的元素, 这个API很像filter，参数也都一样，但是只会返回一个结果
async.detect([13, 44, 23], function(item, callback){

  callback(item > 37);

}, function(result){

  console.log("detect：" + result);// detect：44

});



//同名函数any。在数组中找至少一个元素，类似于filter和detect。区别在于，filter和detect是返回找到的元素，而some是返回bool
async.some([6, 3, 9, 16, 2, 15], function (item, callback) {
  callback(item > 9);

}, function (result) {

  console.log("some:" + result);// some:true

});


//数组元素排序
var person1 = {"name": "aaa", age: 79};
var person2 = {"name": "bbb", age: 23};
var person3 = {"name": "ccc", age: 54};

async.sortBy([person1, person2, person3], function (person, callback) {

  callback(null, person.age);

}, function (err, sorted) {

  for (var index in sorted) {
    console.log("sortBy:" + sorted[index].age); // sortBy:23
                                                // sortBy:54
                                                // sortBy:79
  }

});


//瀑布 执行方法，后面依赖前面的,
//waterfall和series函数有很多相似之处，都是按照顺序执行。
//不同之处是waterfall每个函数产生的值，都将传给下一个函数，而series则没有这个功能
async.waterfall([
  function (callback) {
    callback(null, 1, 2);
  },
  function (arg1, arg2, callback) {
    callback(null, arg1 + arg2 + 3);
  },
  function (arg1, callback) {
    callback(null, arg1 + 4);
  }
], function (err, result) {
  console.log("waterfall:" + result); // waterfall:10
});